﻿using QW.Core.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace QW.Core.IOC.Dictionary
{
    /// <summary>
    /// 字典容器
    /// </summary>
    public class DictionaryIOCContainer : IIOCContainer
    {
        private static Dictionary<Type, LifetimeObject> objectDefine = new Dictionary<Type, LifetimeObject>();
        private static ThreadLocal<Dictionary<Type, object>> _threadBox = new ThreadLocal<Dictionary<Type, object>>();
        /// <summary>
        /// 线程容器
        /// </summary>
        private static Dictionary<Type, object> threadBox
        {
            get
            {
                if (!_threadBox.IsValueCreated)
                {
                    _threadBox.Value = new Dictionary<Type, object>();
                }
                return _threadBox.Value;
            }
        }
        /// <summary>
        /// 构建
        /// </summary>
        public void Build()
        {

        }
        /// <summary>
        /// 注册类型
        /// </summary>
        /// <param name="TT">目标类型，例：接口</param>
        /// <param name="T">实例源类型，例：接口实现</param>
        /// <param name="lifetimeScope">生命周期 </param>
        public void RegisterType(Type TT, Type T, InstanceLifetimeScope lifetimeScope = InstanceLifetimeScope.Transient)
        {
            var st = T;
            var ls = (InstanceLifetimeScope)lifetimeScope;
            LifetimeObject _object = new LifetimeObject();
            _object.TargetType = TT;
            if (objectDefine.ContainsKey(_object.TargetType))
            {
                _object = objectDefine[_object.TargetType];
                if (_object.SourceType != st)
                {
                    _object.SourceType = st;
                }
            }
            _object.SourceType = st;
            _object.LifetimeScope = ls;
            objectDefine[_object.TargetType] = _object;
        }
        /// <summary>
        /// 注册类型
        /// </summary>
        /// <typeparam name="TT">目标类型，例：接口</typeparam>
        /// <typeparam name="T">实例源类型，例：接口实现</typeparam>
        /// <param name="lifetimeScope">生命周期</param>
        public void RegisterType<TT, T>(InstanceLifetimeScope lifetimeScope = InstanceLifetimeScope.Transient)
        {
            RegisterType(typeof(TT), typeof(T), lifetimeScope);
        }
        /// <summary>
        /// 注册类型
        /// </summary>
        /// <typeparam name="TT">目标类型，例：接口</typeparam>
        /// <param name="T">实例源类型，例：接口实现</param>
        /// <param name="lifetimeScope">生命周期，可参考InstanceLifetimeScope</param>
        public void RegisterType<TT>(Type T, InstanceLifetimeScope lifetimeScope = InstanceLifetimeScope.Transient)
        {
            RegisterType(typeof(TT), T, lifetimeScope);
        }

        /// <summary>
        /// 反转实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Resolve<T>()
        {
            return (T)Resolve(typeof(T));
        }
        /// <summary>
        /// 反转实例
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
        public object Resolve(Type T)
        {
            var rt = T;
            if (!objectDefine.ContainsKey(rt))
            {
                throw new QWBaseException("该服务未在框架中注册");
            }
            var _object = objectDefine[rt];
            object result = null;
            switch (_object.LifetimeScope)
            {
                case InstanceLifetimeScope.Singleton:
                    if (_object.Object == null)
                    {
                        _object.Object = Activator.CreateInstance(_object.SourceType);
                    }
                    result = _object.Object;
                    break;
                case InstanceLifetimeScope.Scoped:
                case InstanceLifetimeScope.Request:
                    if (threadBox.ContainsKey(_object.TargetType))
                    {
                        result = threadBox[_object.TargetType];
                    }
                    else
                    {
                        result = Activator.CreateInstance(_object.SourceType);
                        threadBox[_object.TargetType] = result;
                    }
                    break;
                default:
                    result = Activator.CreateInstance(_object.SourceType); //返回新实例
                    break;
            }
            return result;

        }
    }
    /// <summary>
    /// 生命周期对象
    /// </summary>
    internal class LifetimeObject
    {
        /// <summary>
        /// 源类型
        /// </summary>
        public Type SourceType { get; set; }
        /// <summary>
        /// 目标类型
        /// </summary>
        public Type TargetType { get; set; }
        /// <summary>
        /// 对象
        /// </summary>
        public object Object { get; set; }
        /// <summary>
        /// 生命周期
        /// </summary>
        public InstanceLifetimeScope LifetimeScope { get; set; }
    }
}
